admin: Write out correct version fields in boot/loader/entries files
authorColin Walters <walters@verbum.org>
Wed, 21 Aug 2013 22:48:00 +0000 (18:48 -0400)
committerColin Walters <walters@verbum.org>
Thu, 22 Aug 2013 09:46:11 +0000 (05:46 -0400)
Before, we were writing the "bootversion", which is either 0 or 1, for
all entries.  This is completely wrong; the idea of the "version"
field is to compare between entries.

Fix this by writing out the inverted index - internally, index 0 is
the *first* boot entry, so we give it the highest version number, and
index N is the last, so give it version 0.

Then fix the deployment sorting code to correctly reverse the version
number comparison, so we read back the right order.

In practice before this bug didn't matter because "normally" you only
have at most two deployments.

https://bugzilla.gnome.org/show_bug.cgi?id=706546

src/ostree/ot-admin-deploy.c
src/ostree/ot-admin-functions.c
tests/test-admin-deploy-1.sh

index 21db4834a069d9bb1ca6522e38bafb8ad22dcb03..deda4eb232da995495ec0514b545ade5f5f8f946 100644 (file)
@@ -791,10 +791,16 @@ parse_os_release (const char *contents,
   return ret;
 }
 
+/*
+ * install_deployment_kernel:
+ * 
+ * Write out an entry in /boot/loader/entries for @deployment.
+ */
 static gboolean
 install_deployment_kernel (GFile          *sysroot,
                            int             new_bootversion,
                            OtDeployment   *deployment,
+                           guint           n_deployments,
                            GCancellable   *cancellable,
                            GError        **error)
 
@@ -901,7 +907,7 @@ install_deployment_kernel (GFile          *sysroot,
                                val);
   ot_config_parser_set (bootconfig, "title", title_key);
 
-  version_key = g_strdup_printf ("%d", ot_deployment_get_bootserial (deployment));
+  version_key = g_strdup_printf ("%d", n_deployments - ot_deployment_get_index (deployment));
   ot_config_parser_set (bootconfig, "version", version_key);
 
   linux_relpath = g_file_get_relative_path (bootdir, dest_kernel_path);
@@ -1000,7 +1006,8 @@ ot_admin_write_deployments (GFile             *sysroot,
       for (i = 0; i < new_deployments->len; i++)
         {
           OtDeployment *deployment = new_deployments->pdata[i];
-          if (!install_deployment_kernel (sysroot, new_bootversion, deployment,
+          if (!install_deployment_kernel (sysroot, new_bootversion,
+                                          deployment, new_deployments->len,
                                           cancellable, error))
             {
               g_prefix_error (error, "Installing kernel: ");
index 7dfc30f1ee5a0c65341bbf340f499a1babf71672..397aed25b49cd89d225c6d94ce67e35a396082ed 100644 (file)
@@ -717,8 +717,8 @@ list_deployments_process_one_boot_entry (GFile               *sysroot,
 }
 
 static gint
-compare_deployments_by_boot_loader_version (gconstpointer     a_pp,
-                                            gconstpointer     b_pp)
+compare_deployments_by_boot_loader_version_reversed (gconstpointer     a_pp,
+                                                     gconstpointer     b_pp)
 {
   OtDeployment *a = *((OtDeployment**)a_pp);
   OtDeployment *b = *((OtDeployment**)b_pp);
@@ -728,11 +728,15 @@ compare_deployments_by_boot_loader_version (gconstpointer     a_pp,
   const char *b_version = ot_config_parser_get (b_bootconfig, "version");
   
   if (a_version && b_version)
-    return strverscmp (a_version, b_version);
+    {
+      int r = strverscmp (a_version, b_version);
+      /* Reverse */
+      return -r;
+    }
   else if (a_version)
-    return 1;
-  else
     return -1;
+  else
+    return 1;
 }
 
 gboolean
@@ -766,7 +770,7 @@ ot_admin_list_deployments (GFile               *sysroot,
         goto out;
     }
 
-  g_ptr_array_sort (ret_deployments, compare_deployments_by_boot_loader_version);
+  g_ptr_array_sort (ret_deployments, compare_deployments_by_boot_loader_version_reversed);
   for (i = 0; i < ret_deployments->len; i++)
     {
       OtDeployment *deployment = ret_deployments->pdata[i];
index 0119586ba1ab4a2a1a1593ed0f774125314f4332..fbf9fc27bafb302da6f8b41094b01c3dc6980811 100755 (executable)
@@ -62,6 +62,8 @@ assert_file_has_content sysroot/boot/loader/entries/ostree-testos-${rev}-0.conf
 assert_file_has_content sysroot/ostree/deploy/testos/deploy/${rev}.1/etc/os-release 'NAME=TestOS'
 assert_file_has_content sysroot/ostree/boot.0/testos/${bootcsum}/0/etc/os-release 'NAME=TestOS'
 
+ostree admin --sysroot=sysroot status
+
 echo "ok second deploy"
 
 ostree admin --sysroot=sysroot deploy --os=testos testos:testos/buildmaster/x86_64-runtime
@@ -123,6 +125,8 @@ assert_not_has_file sysroot/ostree/deploy/testos/deploy/${rev}.3/etc/aconfigfile
 
 echo "ok upgrade bare"
 
+ostree admin --sysroot=sysroot status
+
 os_repository_new_commit
 ostree --repo=sysroot/ostree/repo remote add testos file://$(pwd)/testos-repo testos/buildmaster/x86_64-runtime
 ostree admin --sysroot=sysroot upgrade --os=testos
@@ -134,14 +138,16 @@ assert_file_has_content sysroot/ostree/deploy/testos/deploy/${newrev}.0/etc/os-r
 
 echo "ok upgrade"
 
+ostree admin --sysroot=sysroot status
+
 assert_file_has_content sysroot/ostree/deploy/testos/deploy/${newrev}.0/etc/os-release 'NAME=TestOS'
 assert_file_has_content sysroot/ostree/deploy/testos/deploy/${origrev}.4/etc/os-release 'NAME=TestOS'
-ostree admin --sysroot=sysroot undeploy 1
+ostree admin --sysroot=sysroot undeploy 2
 assert_file_has_content sysroot/ostree/deploy/testos/deploy/${newrev}.0/etc/os-release 'NAME=TestOS'
 assert_not_has_dir sysroot/ostree/deploy/testos/deploy/${origrev}.4
 
 assert_file_has_content sysroot/ostree/deploy/testos/deploy/${origrev}.3/etc/os-release 'NAME=TestOS'
-ostree admin --sysroot=sysroot undeploy 3
+ostree admin --sysroot=sysroot undeploy 2
 assert_not_has_dir sysroot/ostree/deploy/testos/deploy/${origrev}.3
 
 assert_file_has_content sysroot/ostree/deploy/testos/deploy/${newrev}.0/etc/os-release 'NAME=TestOS'